home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / djgpp / src / gas-211 / gas / cond.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  6.6 KB  |  263 lines

  1. /* cond.c - conditional assembly pseudo-ops, and .include
  2.    Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GAS, the GNU Assembler.
  5.  
  6.    GAS is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    GAS is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GAS; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "as.h"
  21.  
  22. #include "obstack.h"
  23.  
  24. /* This is allocated to grow and shrink as .ifdef/.endif pairs are scanned. */
  25. struct obstack cond_obstack;
  26.  
  27. struct file_line
  28.   {
  29.     char *logical_file;
  30.     int logical_line;
  31.     char *physical_file;
  32.     int physical_line;
  33.   };                /* file_line */
  34.  
  35. /* This is what we push and pop. */
  36. struct conditional_frame
  37.   {
  38.     struct file_line if_file_line;    /* the source file & line number of the "if" */
  39.     struct file_line else_file_line;    /* the source file & line of the "else" */
  40.     struct conditional_frame *previous_cframe;
  41.     int else_seen;        /* have we seen an else yet? */
  42.     int ignoring;        /* if we are currently ignoring input. */
  43.     int dead_tree;        /* if a conditional at a higher level is ignoring input. */
  44.   };                /* conditional_frame */
  45.  
  46. #if __STDC__ == 1
  47.  
  48. static void get_file_line (struct file_line *into);
  49. static void initialize_cframe (struct conditional_frame *cframe);
  50. static void set_file_line (struct file_line *from);
  51.  
  52. #else
  53.  
  54. static void get_file_line ();
  55. static void initialize_cframe ();
  56. static void set_file_line ();
  57.  
  58. #endif
  59.  
  60. static struct conditional_frame *current_cframe = NULL;
  61.  
  62. void 
  63. s_ifdef (arg)
  64.      int arg;
  65. {
  66.   register char *name;        /* points to name of symbol */
  67.   register struct symbol *symbolP;    /* Points to symbol */
  68.   struct conditional_frame cframe;
  69.  
  70.   SKIP_WHITESPACE ();        /* Leading whitespace is part of operand. */
  71.   name = input_line_pointer;
  72.  
  73.   if (!is_name_beginner (*name))
  74.     {
  75.       as_bad ("invalid identifier for \".ifdef\"");
  76.       obstack_1grow (&cond_obstack, 0);
  77.     }
  78.   else
  79.     {
  80.       get_symbol_end ();
  81.       ++input_line_pointer;
  82.       symbolP = symbol_find (name);
  83.  
  84.       initialize_cframe (&cframe);
  85.       cframe.ignoring = cframe.dead_tree || !((symbolP != 0) ^ arg);
  86.       current_cframe = (struct conditional_frame *) obstack_copy (&cond_obstack, &cframe, sizeof (cframe));
  87.     }                /* if a valid identifyer name */
  88.  
  89.   return;
  90. }                /* s_ifdef() */
  91.  
  92. void 
  93. s_if (arg)
  94.      int arg;
  95. {
  96.   expressionS operand;
  97.   struct conditional_frame cframe;
  98.  
  99.   SKIP_WHITESPACE ();        /* Leading whitespace is part of operand. */
  100.   expr (0, &operand);
  101.  
  102.   if (operand.X_add_symbol != NULL
  103.       || operand.X_subtract_symbol != NULL)
  104.     {
  105.       as_bad ("non-constant expression in \".if\" statement");
  106.     }                /* bad condition */
  107.  
  108.   /* If the above error is signaled, this will dispatch
  109.        using an undefined result.  No big deal.  */
  110.   initialize_cframe (&cframe);
  111.   cframe.ignoring = cframe.dead_tree || !((operand.X_add_number != 0) ^ arg);
  112.   current_cframe = (struct conditional_frame *) obstack_copy (&cond_obstack, &cframe, sizeof (cframe));
  113.   return;
  114. }                /* s_if() */
  115.  
  116. void 
  117. s_endif (arg)
  118.      int arg;
  119. {
  120.   struct conditional_frame *hold;
  121.  
  122.   if (current_cframe == NULL)
  123.     {
  124.       as_bad ("\".endif\" without \".if\"");
  125.     }
  126.   else
  127.     {
  128.       hold = current_cframe;
  129.       current_cframe = current_cframe->previous_cframe;
  130.       obstack_free (&cond_obstack, hold);
  131.     }                /* if one pop too many */
  132.  
  133.   return;
  134. }                /* s_endif() */
  135.  
  136. void 
  137. s_else (arg)
  138.      int arg;
  139. {
  140.   if (current_cframe == NULL)
  141.     {
  142.       as_bad (".else without matching .if - ignored");
  143.  
  144.     }
  145.   else if (current_cframe->else_seen)
  146.     {
  147.       struct file_line hold;
  148.       as_bad ("duplicate \"else\" - ignored");
  149.  
  150.       get_file_line (&hold);
  151.       set_file_line (¤t_cframe->else_file_line);
  152.       as_bad ("here is the previous \"else\".");
  153.       set_file_line (¤t_cframe->if_file_line);
  154.       as_bad ("here is the matching \".if\".");
  155.       set_file_line (&hold);
  156.  
  157.     }
  158.   else
  159.     {
  160.       get_file_line (¤t_cframe->else_file_line);
  161.  
  162.       if (!current_cframe->dead_tree)
  163.     {
  164.       current_cframe->ignoring = !current_cframe->ignoring;
  165.     }            /* if not a dead tree */
  166.  
  167.       current_cframe->else_seen = 1;
  168.     }                /* if error else do it */
  169.  
  170.   return;
  171. }                /* s_else() */
  172.  
  173. void 
  174. s_ifeqs (arg)
  175.      int arg;
  176. {
  177.   as_bad ("ifeqs not implemented.");
  178.  
  179.   return;
  180. }                /* s_ifeqs() */
  181.  
  182. void 
  183. s_end (arg)
  184.      int arg;
  185. {
  186.   return;
  187. }                /* s_end() */
  188.  
  189. int 
  190. ignore_input ()
  191. {
  192.   char *ptr = obstack_next_free (&cond_obstack);
  193.  
  194.   /* We cannot ignore certain pseudo ops.  */
  195.   if (input_line_pointer[-1] == '.'
  196.       && ((input_line_pointer[0] == 'i'
  197.        && (!strncmp (input_line_pointer, "if", 2)
  198.            || !strncmp (input_line_pointer, "ifdef", 5)
  199.            || !strncmp (input_line_pointer, "ifndef", 6)))
  200.       || (input_line_pointer[0] == 'e'
  201.           && (!strncmp (input_line_pointer, "else", 4)
  202.           || !strncmp (input_line_pointer, "endif", 5)))))
  203.     {
  204.       return 0;
  205.     }
  206.  
  207.   return ((current_cframe != NULL) && (current_cframe->ignoring));
  208. }                /* ignore_input() */
  209.  
  210. static void 
  211. initialize_cframe (cframe)
  212.      struct conditional_frame *cframe;
  213. {
  214.   memset (cframe, 0, sizeof (*cframe));
  215.   get_file_line (&(cframe->if_file_line));
  216.   cframe->previous_cframe = current_cframe;
  217.   cframe->dead_tree = current_cframe != NULL && current_cframe->ignoring;
  218.  
  219.   return;
  220. }                /* initialize_cframe() */
  221.  
  222. static void 
  223. get_file_line (into)
  224.      struct file_line *into;
  225. {
  226.   extern char *logical_input_file;
  227.   extern char *physical_input_file;
  228.   extern int logical_input_line;
  229.   extern int physical_input_line;
  230.  
  231.   into->logical_file = logical_input_file;
  232.   into->logical_line = logical_input_line;
  233.   into->physical_file = physical_input_file;
  234.   into->physical_line = physical_input_line;
  235.  
  236.   return;
  237. }                /* get_file_line() */
  238.  
  239. static void 
  240. set_file_line (from)
  241.      struct file_line *from;
  242. {
  243.   extern char *logical_input_file;
  244.   extern char *physical_input_file;
  245.   extern int logical_input_line;
  246.   extern int physical_input_line;
  247.  
  248.   logical_input_file = from->logical_file;
  249.   logical_input_line = from->logical_line;
  250.   physical_input_file = from->physical_file;
  251.   physical_input_line = from->physical_line;
  252.   return;
  253. }                /* set_file_line() */
  254.  
  255. /*
  256.  * Local Variables:
  257.  * fill-column: 131
  258.  * comment-column: 0
  259.  * End:
  260.  */
  261.  
  262. /* end of cond.c */
  263.